<template>
	<div class="default-main">

		<cus-form id="creature-form" collapsable icon="fa fa-search" label="搜索">
			<template #title-after>
				<el-button icon="el-icon-Search" size="small" type="primary" @click.stop="handleSearch">
					搜索
				</el-button>
				<el-button icon="el-icon-Refresh" size="small" type="primary" @click.stop="resetSearch">
					重置
				</el-button>
			</template>
			<template #form>
				<el-form ref="itemSearchForm" :model="params" label-width="auto">
					<el-row :gutter="20" justify="start">
						<el-col :span="8">
							<el-form-item label="生物名称">
								<el-input v-model="params.creatureName_like" clearable placeholder="模糊查询" @keyup.enter="handleSearch"></el-input>
							</el-form-item>
						</el-col>
						<el-col :span="8">
							<el-form-item label="类别">
								<el-cascader
										v-model="params.classificationIdList"
										:options="classificationOptionList"
										:props="{ expandTrigger: 'hover', checkStrictly: false, multiple: true, emitPath: false }"
										:show-all-levels="false"
										clearable
										collapse-tags
										collapse-tags-tooltip
										filterable
										placeholder="不限"
										@change="classificationIdListChanged"
								></el-cascader>
							</el-form-item>
						</el-col>
						<el-col :span="8">
							<el-form-item label="生物描述">
								<el-input v-model="params.description_like" clearable placeholder="模糊查询" @keyup.enter="handleSearch"></el-input>
							</el-form-item>
						</el-col>
					</el-row>
					<el-row :gutter="20" justify="start">
						<el-col :span="8">
							<el-form-item label="耐久度不小于">
								<el-input v-model="params.durability_ge" :max="MAX_INTEGER" :min="1" :step="1" class="w100" clearable controls-position="right"
								          step-strictly type="number" @change="handleSearch"/>
							</el-form-item>
						</el-col>
						<el-col :span="8">
							<el-form-item label="伤害不小于">
								<el-input v-model="params.damage_ge" :max="MAX_INTEGER" :min="1" :step="1" class="w100" clearable controls-position="right"
								          step-strictly
								          type="number" @change="handleSearch"/>
							</el-form-item>
						</el-col>
					</el-row>
				</el-form>
			</template>
		</cus-form>

		<cus-table-title id="creature-table-title" icon="iconfont icon-animal" label="生物">
			<template #after>
				<el-button v-if="isAdmin()" icon="el-icon-Plus" size="small" style="margin-left: 20px" type="primary" @click="toAdd">
					新增
				</el-button>
			</template>
		</cus-table-title>
		<el-table ref="tableRef" v-loading="tableLoading" :data="creatureTableData" :header-cell-class-name="handleHeaderCellClass" :max-height="tableMaxHeight"
		          border class="cus-table" fit highlight-current-row @sort-change="elTableSortChange($event, params.orderby, handleSearch)">
			<el-table-column align="center" label="序号" width="60">
				<template v-slot="scope">
					{{ initTableIndex(pageRef, scope.$index) }}
				</template>
			</el-table-column>
			<el-table-column align="center" label="名称" min-width="200" prop="creatureName"></el-table-column>
			<el-table-column align="center" label="图片" width="150">
				<template v-slot="scope">
					<el-image v-if="scope.row.image" :src="getImage(scope.row.image)" fit="contain"
					          style="width: 100px; height: 100px;cursor: pointer" @click="toUpdate(scope.row)"
					></el-image>
				</template>
			</el-table-column>
			<el-table-column v-if="isAdmin()" align="center" label="同级排序" prop="sort" width="90"></el-table-column>
			<el-table-column align="center" label="类别" prop="classificationName" sort-by="classificationId" sortable="custom" width="150">
				<template v-slot="scope">
					<el-tag>{{ scope.row.classificationName || '/' }}</el-tag>
				</template>
			</el-table-column>
			<el-table-column align="center" label="耐久度" prop="durability" sortable="custom" width="150">
				<template v-slot="scope">
					<el-tag v-if="scope.row.durability === -1" type="info">/</el-tag>
					<el-tag v-else>{{ scope.row.durability }}</el-tag>
				</template>
			</el-table-column>
			<el-table-column align="center" label="伤害" prop="damage" sortable="custom" width="150">
				<template v-slot="scope">
					<el-tag v-if="!scope.row.damage || scope.row.damage.length === 0" type="info">/</el-tag>
					<el-space v-else>
						<el-tag v-for="val in scope.row.damage">
							{{ val }}
						</el-tag>
					</el-space>
				</template>
			</el-table-column>
			<el-table-column align="center" label="描述" min-width="450" prop="description">
				<template v-slot="scope">
					<div class="pre-wrap">{{ scope.row.description }}</div>
				</template>
			</el-table-column>
			<el-table-column v-if="isAdmin()" :label="String($t('table.actions'))" :width="120" align="center" fixed="right">
				<template v-slot="scope">
					<el-dropdown>
						<el-button icon="el-icon-MoreFilled" plain round size="small"></el-button>
						<template #dropdown>
							<el-dropdown-menu>
								<el-dropdown-item :disabled="!hasPermission('g-creature:saveCreature')" icon="el-icon-Edit" @click="toUpdate(scope.row)">
									编辑
								</el-dropdown-item>
								<el-dropdown-item :disabled="!hasPermission('g-creature:deleteCreature')" icon="el-icon-Delete" @click="deleteItem(scope.row)">
									删除
								</el-dropdown-item>
							</el-dropdown-menu>
						</template>
					</el-dropdown>
				</template>
			</el-table-column>
		</el-table>
		<cus-pagination id="creature-pagination" ref="pageRef" v-model="creatureTableData" v-model:loading="tableLoading" :pageSize="10" :params="params"
		                url="/game/g-creature/readOnly/searchCreatureByPage"/>

		<!-- 对话框（新增、修改） -->
		<el-dialog v-model="dialogVisible" :close-on-click-modal="false" :close-on-press-escape="true" :title="dialogTitle"
		           append-to-body center class="cus-dialog" destroy-on-close draggable width="50%" @closed="dialogClosed">
			<div v-if="creatureImage" class="cus-center" style="padding-bottom: 20px">
				<el-image :src="getImage(creatureImage)" fit="contain" style="width: 128px; height: 128px"></el-image>
			</div>
			<el-form ref="editFormRef" :disabled="!hasPermission('g-creature:saveCreature')" :model="creature" :rules="rules" label-width="auto">
				<el-form-item label="生物名称" prop="creatureName">
					<el-input v-model="creature.creatureName" clearable maxlength="100"></el-input>
				</el-form-item>
				<el-form-item label="生物描述" prop="description">
					<el-input v-model="creature.description" :autosize="{ minRows: 4, maxRows: 4}" clearable maxlength="500" type="textarea"></el-input>
				</el-form-item>
				<el-row :gutter="20" justify="start">
					<el-col :span="8">
						<el-form-item label="类别" prop="classificationId">
							<el-cascader
									v-model="creature.classificationId"
									:options="classificationOptionList"
									:props="{ expandTrigger: 'hover', checkStrictly: false, emitPath: false }"
									:show-all-levels="true"
									clearable
									filterable
							></el-cascader>
						</el-form-item>
					</el-col>
					<el-col :span="8">
						<el-form-item label="同级排序" prop="sort">
							<el-input-number v-model="creature.sort" :min="0" :step="1" class="w100" controls-position="right" step-strictly/>
						</el-form-item>
					</el-col>
				</el-row>
				<el-row :gutter="20" justify="start">
					<el-col :span="8">
						<el-form-item label="耐久度" prop="durability">
							<el-input-number v-model="creature.durability" :max="MAX_INTEGER" :min="-1" :step="1" class="w100" clearable
							                 controls-position="right" step-strictly/>
						</el-form-item>
					</el-col>
					<el-col :span="16">
						<el-form-item label="伤害" prop="damage">
							<el-space wrap>
								<el-tag v-for="(val, index) in creature.damage" :key="'creature-damage_' + index" closable
								        @close="() => (<number[]>creature.damage).splice(index, 1)">
									{{ val }}
								</el-tag>
								<el-input
										v-if="newDamageInputVisible"
										ref="newDamageInputRef"
										v-model="newDamageValue"
										size="small"
										style="width: auto"
										@blur="handleNewDamageConfirm"
										@keyup.enter="handleNewDamageConfirm"
								/>
								<el-button v-else icon="el-icon-Plus" size="small" @click="showNewDamageInput"></el-button>
							</el-space>
						</el-form-item>
					</el-col>
				</el-row>
				<el-form-item label="图片地址" prop="image">
					<el-input v-model="creature.image" clearable maxlength="500"></el-input>
				</el-form-item>
			</el-form>
			<template #footer>
				<el-button v-auth="'g-creature:saveCreature'" icon="el-icon-CircleCheck" type="primary" @click="save">
					保存
				</el-button>
				<el-button icon="el-icon-CircleClose" type="warning" @click="dialogVisible = false">
					取消
				</el-button>
			</template>
		</el-dialog>

	</div>
</template>

<script lang="ts" name="Creature" setup>

import {nextTick, onActivated, onMounted, reactive, ref} from 'vue'
import type {FormInstance, FormRules, InputInstance, TableColumnCtx, TableInstance} from 'element-plus'
import {ElMessageBox} from 'element-plus'
import {elTableHeaderCellClassName, elTableSortChange, exist, focusFormErrorElement, getImage, initTableIndex, messageError, messageSuccess} from '@/utils/commonUtil'
import {useI18n} from 'vue-i18n'
import CusPagination from '@/components/cus-pagination.vue'
import CusTableTitle from '@/components/cus-table-title.vue'
import {calcMaxHeight} from '@/utils/layoutUtil'
import {debounce, type DebouncedFunc} from 'lodash-es'
import {useEventListener} from '@vueuse/core'
import {onBeforeRouteLeave} from 'vue-router'
import {MAX_INTEGER} from '@/utils/constantsUtil'
import {hasPermission, isAdmin} from '@/utils/authUtil'
import {deleteCreatureApi, getCreatureCascadeClassificationApi, saveCreatureApi} from '@/api/gameData/creature.api'
import CusForm from '@/components/cus-form.vue'

const {t} = useI18n()

const pageRef = ref()
const editFormRef = ref<FormInstance>()
const tableRef = ref<TableInstance>()

const tableMaxHeight = ref<number>(800)
const params = reactive<SearchCreatureRequest>({
	creatureName_like: undefined,
	classificationIdList: [],
	description_like: undefined,
	durability_ge: undefined,
	damage_ge: undefined,
	orderby: []
})
const tableLoading = ref(false)
const creatureTableData = ref<GCreature[]>([])
const classificationOptionList = ref<CascadeClassificationVo[]>([])
const creature = reactive<GCreature>({
	id: undefined,
	creatureName: undefined,
	description: undefined,
	durability: -1,
	damage: undefined,
	image: undefined,
	classificationId: undefined,
	sort: 0
})
const creatureImage = ref<string>()
const dialogTitle = ref<string>()
const dialogVisible = ref(false)
const rules = reactive<FormRules>({
	creatureName: [
		{required: true, message: '请输入生物名称', trigger: 'change'}
	],
	description: [
		{required: true, message: '请输入生物描述', trigger: 'change'}
	],
	fluid: [
		{required: true, message: '请选择物理形态', trigger: 'change'}
	],
	stack: [
		{required: true, message: '请输入最大堆叠数量', trigger: 'change'}
	],
	energy: [
		{required: true, message: '请输入能量', trigger: 'change', min: -1, max: MAX_INTEGER, type: 'number'}
	],
	resourceSinkPoints: [
		{required: true, message: '请输入资源槽点数', trigger: 'change', min: -1, max: MAX_INTEGER, type: 'number'}
	],
	damage: [
		{required: false, message: '请输入伤害值', trigger: 'change', min: -1, max: MAX_INTEGER, type: 'array'}
	],
	equippable: [
		{required: true, message: '请选择能否装备', trigger: 'change'}
	],
	equipmentLocation: [
		{required: true, message: '请选择装备位置', trigger: 'change'}
	],
	handmade: [
		{required: true, message: '请选择能否手搓', trigger: 'change'}
	],
	sort: [
		{required: true, message: '请输入同级排序', trigger: 'change'}
	],
	classificationId: [
		{required: true, message: '请选择类别', trigger: 'change'}
	]
})

const newDamageInputRef = ref<InputInstance>()
const newDamageValue = ref<number>()
const newDamageInputVisible = ref<boolean>()

const showNewDamageInput = () => {
	newDamageInputVisible.value = true
	nextTick(() => {
		newDamageInputRef.value?.input?.focus()
	})
}

const handleNewDamageConfirm = () => {
	if (exist(newDamageValue.value)) {
		if (!Number.isSafeInteger(Number(newDamageValue.value)) || newDamageValue.value! < 1) {
			messageError('伤害值请输入正整数')
			return
		}
		if (!creature.damage) {
			creature.damage = []
		}
		creature.damage.push(newDamageValue.value!)
	}
	newDamageInputVisible.value = false
	newDamageValue.value = undefined
}

const dialogClosed = () => {
	newDamageInputVisible.value = false
	newDamageValue.value = undefined
}

/**
 * 计算表格最大高度
 */
const getTableMaxHeight: DebouncedFunc<() => typeof getTableMaxHeight> = debounce(() => {
	tableMaxHeight.value = calcMaxHeight('#creature-form', '#creature-table-title', '#creature-pagination')
	return getTableMaxHeight
}, 100, {
	leading: true,
	trailing: false,
	maxWait: 100
})

const handleHeaderCellClass = (args: { rows: GCreature[], column: TableColumnCtx<GCreature>, rowIndex: number, columnIndex: number }) => {
	elTableHeaderCellClassName(args, params.orderby)
}

const classificationIdListChanged = (value: number[]) => {
	if (value && value.length === 1) {
		params.orderby.push({
			field: 'sort',
			order: 'ascending'
		})
	} else {
		params.orderby = params.orderby.filter(item => item.field !== 'sort')
	}
	handleSearch()
}

const handleSearch = () => {
	pageRef.value!.reload()
}

const resetParams = () => {
	params.creatureName_like = undefined
	params.classificationIdList = []
	params.description_like = undefined
	params.durability_ge = undefined
	params.damage_ge = undefined
	params.orderby = []
	// 清除多列的排序状态
	for (const column of tableRef.value?.store.states.columns.value) {
		column.order = null
	}
}

const resetSearch = () => {
	resetParams()
	handleSearch()
}

const resetItem = () => {
	creature.id = undefined
	creature.creatureName = undefined
	creature.description = undefined
	creature.durability = -1
	creature.damage = undefined
	creature.image = undefined
	creature.classificationId = undefined
	creature.sort = 0
}

const toAdd = () => {
	resetItem()
	creatureImage.value = undefined
	dialogVisible.value = true
	dialogTitle.value = '新增生物'
}

const toUpdate = (row: GCreature) => {
	resetItem()
	Object.assign(creature, JSON.parse(JSON.stringify(row)))
	creatureImage.value = creature.image
	dialogVisible.value = true
	dialogTitle.value = '编辑生物信息'
}

const save = () => {
	editFormRef.value!.validate(isValid => {
		if (isValid) {
			saveCreatureApi(creature).then(() => {
				if (creature.id) {
					messageSuccess(t('successMessage.update'))
				} else {
					messageSuccess(t('successMessage.add'))
				}
				dialogVisible.value = false
				pageRef.value!.buildData()
			})
		} else {
			focusFormErrorElement()
		}
	})
}

const deleteItem = (row: GCreature) => {
	ElMessageBox.confirm(row.creatureName, '删除该生物？', {
		confirmButtonText: '确定',
		cancelButtonText: '取消',
		type: 'warning',
		draggable: true
	}).then(() => {
		deleteCreatureApi(row.id!).then(() => {
			messageSuccess(t('successMessage.delete'))
			pageRef.value!.buildData()
		})
	}).catch(() => {
	})
}

// 生物类别
getCreatureCascadeClassificationApi().then(response => {
	classificationOptionList.value = response.data
})

onMounted(() => {
	useEventListener(window, 'resize', getTableMaxHeight()!)
})

// 该页面开启缓存且首次或后续进入时执行，刷新页面不执行
onActivated(() => {
	useEventListener(window, 'resize', getTableMaxHeight()!)
})

onBeforeRouteLeave(() => {
	window.removeEventListener('resize', getTableMaxHeight)
})

</script>

<style lang="scss" scoped>
</style>
